package com.erpanderp.wam.ac.view.reimbursement;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.swing.SwingWorker;

import com.erpanderp.wam.ac.model.entity.reimbursement.BoardingExpense;
import com.erpanderp.wam.ac.model.entity.reimbursement.Currency;
import com.erpanderp.wam.ac.model.entity.reimbursement.LodgingExpense;
import com.erpanderp.wam.ac.model.entity.reimbursement.TransportExpense;
import com.erpanderp.wam.ac.model.entity.reimbursement.TravelExpense;
import com.erpanderp.wam.ac.model.entity.reimbursement.TravelMiscExpense;
import com.erpanderp.wam.ac.model.entity.travel.TravelExpenseAmount;
import com.erpanderp.wam.ac.model.entity.travel.TravelRequest;
import com.erpanderp.wam.ac.model.service.reimbursement.TravelReimbursementDAO;
import com.erpanderp.wam.ac.model.service.travel.TravelExpenseAmountDAO;
import com.erpanderp.wam.ac.model.service.travel.TravelRequestDAO;
import com.erpanderp.wam.adm.model.entity.CustomLookup;
import com.erpanderp.wam.adm.model.entity.LookupValue;
import com.erpanderp.wam.adm.model.service.CustomLookupDAO;
import com.erpanderp.wam.usm.model.entity.user.Employee;
import com.erpanderp.wam.usm.model.service.user.EmployeeDAO;
import com.erpanderp.wam.util.CommonLookup;
import com.erpanderp.wam.util.EmailUtil;
import com.erpanderp.wam.util.ValidationUtil;
import com.erpanderp.wam.util.WAMHostManager;

@ViewScoped
@ManagedBean
public class ApproveTravelExpenseBean implements Serializable {

	private static final long serialVersionUID = 1L;
	private HttpSession session = (HttpSession) FacesContext
			.getCurrentInstance().getExternalContext().getSession(true);
	ServletContext context = (ServletContext) FacesContext.getCurrentInstance()
			.getExternalContext().getContext();
	HttpServletRequest request = (HttpServletRequest) FacesContext
			.getCurrentInstance().getExternalContext().getRequest();
	private TimeZone timeZone = TimeZone.getDefault();

	private String employeeCode;
	private String travelCode;
	private String travelExpenseCode;
	private String activity;
	private EmailUtil emailUtil;
	private String EMAIL_MESSAGE;
	private float approvalTotal;
	private boolean FORM_VALID;

	private EmployeeDAO employeeDAO = new EmployeeDAO();
	private TravelReimbursementDAO travelReimbursementDAO = new TravelReimbursementDAO();
	private TravelRequestDAO travelRequestDAO = new TravelRequestDAO();
	private CustomLookupDAO customLookupDAO = new CustomLookupDAO();

	private Employee employee = new Employee();
	private TravelExpense travelExpense = new TravelExpense();
	private TravelRequest travelRequest = new TravelRequest();
	
	private List<TransportExpense> transportExpensesDetailsList = new ArrayList<TransportExpense>();
	private List<LodgingExpense> lodgingExpenseDetailsList = new ArrayList<LodgingExpense>();
	private List<BoardingExpense> boardingExpenseDetailsList = new ArrayList<BoardingExpense>();
	private List<TravelMiscExpense> travelMiscExpenseDetailsList = new ArrayList<TravelMiscExpense>();
	private List<Currency> Currencies = new ArrayList<Currency>();
	private List<LookupValue> lookUpValuesList = new ArrayList<LookupValue>();
	private Map<String,String> currencyMap = new HashMap<String, String>();

	private List<TravelExpenseAmount> policyAmounts = new ArrayList<TravelExpenseAmount>();
	private List<TravelExpenseAmount> advanceTakenAmounts = new ArrayList<TravelExpenseAmount>();
	private List<TravelExpenseAmount> approvalAmounts = new ArrayList<TravelExpenseAmount>();
	private List<TravelExpenseAmount> balanceAmounts = new ArrayList<TravelExpenseAmount>();

	private boolean SHOW_NEW_POLICY_SECTION, SHOW_NEW_APPROVAL_AMOUNT_SECTION;
	private TravelExpenseAmount newPolicyAmount, newApprovalAmount, markedPolicyAmount, markedApprovalAmount;
	
	TravelExpenseAmountDAO travelExpenseAmountDAO = new TravelExpenseAmountDAO();
	
	private Employee employeeVP;

	public ApproveTravelExpenseBean() {

		employeeCode = request.getParameter("employeeCode");
		travelCode = request.getParameter("travelCode");
		travelExpenseCode = request.getParameter("expenseCode");
		activity = request.getParameter("activity");

		employee = employeeDAO.getEmployeeByEmployeeCode(employeeCode);
		travelRequest = travelRequestDAO.getTravelRequest(travelCode);
		employeeVP = employeeDAO.getVP();

		travelExpense = travelReimbursementDAO.getTravelExpenseByTravelExpenseCode(travelExpenseCode);
		System.out.println("=1111111111================="+ travelExpense.getAdvancetakenCurrency());
		
		transportExpensesDetailsList.addAll(travelExpense.getTransportExpenses());
		lodgingExpenseDetailsList.addAll(travelExpense.getLodgingExpenses());
		boardingExpenseDetailsList.addAll(travelExpense.getBoardingExpenses());
		travelMiscExpenseDetailsList.addAll(travelExpense.getTravelMiscExpenses());

		lookUpValuesList = customLookupDAO.getLookupValuesListByCustomLookupName(CommonLookup.CURRENCY_CUSTOM_LOOKUP);
		
		if(travelExpense.getAdvancetakenCurrency() ==null || travelExpense.getAdvancetakenCurrency().equals("")){
			for(LookupValue lookUpValue : lookUpValuesList){
				currencyMap.put(lookUpValue.getLookupName(), lookUpValue.getLookupValue());
			}
		}else{
			currencyMap.put(travelExpense.getAdvancetakenCurrency(), travelExpense.getAdvancetakenCurrency());
		}

		//customLookUp = customLookupDAO.getCustomLookUp(CommonLookup.CURRENCY_CUSTOM_LOOKUP);
		//lookUpValuesList = customLookupDAO.getLookupValuesList(customLookUp.getCustomLookId());
	
		for(TravelExpenseAmount expenseAmount : travelRequest.getTravelExpenseAmounts()){
			if(expenseAmount.getAmountType().equals(CommonLookup.TRAVEL_EXPENSE_TYPE_ADVANCE))
				advanceTakenAmounts.add(expenseAmount);
			if(expenseAmount.getAmountType().equals(CommonLookup.TRAVEL_EXPENSE_TYPE_APPROVAL_AMOUNT))
				approvalAmounts.add(expenseAmount);
			if(expenseAmount.getAmountType().equals(CommonLookup.TRAVEL_EXPENSE_POLICY_AMOUNT))
				policyAmounts.add(expenseAmount);
			if(expenseAmount.getAmountType().equals(CommonLookup.TRAVEL_EXPENSE_TYPE_PAYABLE_RECIEVABLE))
				balanceAmounts.add(expenseAmount);
		}
		totalAmountandCurrencyList();
		Collections.sort(advanceTakenAmounts);
		calculateBalance();
	}

	// Total Amount LIST & Currency
	public void totalAmountandCurrencyList() {
		for (LookupValue currency : lookUpValuesList) {
			for (TransportExpense transportExpense : transportExpensesDetailsList) {
				if (transportExpense.getTransportCurrency().equals(
						currency.getLookupValue())) {
					// MATCHED = true;
					boolean ADDED = false;
					for (Currency cur : Currencies) {
						if (currency.getLookupValue().equals(cur.getCurrency())) {
							ADDED = true;
							// change the value
							cur.setAmount(cur.getAmount()
									+ transportExpense.getTransportAmount());
							break;
						}
					}
					if (!ADDED) {
						// create new currentcy and add to the list
						Currency currencyObj = new Currency();
						currencyObj.setAmount(transportExpense
								.getTransportAmount());
						currencyObj.setCurrency(transportExpense
								.getTransportCurrency());
						Currencies.add(currencyObj);
					}
					// break;
				}
			}
			for (LodgingExpense lodgingExpense : lodgingExpenseDetailsList) {
				if (lodgingExpense.getLodgingCurrency().equals(
						currency.getLookupValue())) {
					boolean ADDED = false;
					for (Currency cur : Currencies) {
						if (currency.getLookupValue().equals(cur.getCurrency())) {
							ADDED = true;
							cur.setAmount(cur.getAmount()
									+ lodgingExpense.getLodgingAmount());
							break;
						}
					}
					if (!ADDED) {
						Currency currencyObj = new Currency();
						currencyObj
								.setAmount(lodgingExpense.getLodgingAmount());
						currencyObj.setCurrency(lodgingExpense
								.getLodgingCurrency());
						Currencies.add(currencyObj);
					}
				}
			}
			// FOR BORDING
			for (BoardingExpense boardingExpense : boardingExpenseDetailsList) {
				if (boardingExpense.getBoardingCurrency().equals(
						currency.getLookupValue())) {
					boolean ADDED = false;
					for (Currency cur : Currencies) {
						if (currency.getLookupValue().equals(cur.getCurrency())) {
							ADDED = true;
							cur.setAmount(cur.getAmount()
									+ boardingExpense.getBoardingAmount());
							break;
						}
					}
					if (!ADDED) {
						Currency currencyObj = new Currency();
						currencyObj.setAmount(boardingExpense
								.getBoardingAmount());
						currencyObj.setCurrency(boardingExpense
								.getBoardingCurrency());
						Currencies.add(currencyObj);
					}
				}
			}
			// FOR Travell Misc expense
			for (TravelMiscExpense travelMiscExpense : travelMiscExpenseDetailsList) {
				if (travelMiscExpense.getTravelMiscExpensecurrency().equals(
						currency.getLookupValue())) {
					boolean ADDED = false;
					for (Currency cur : Currencies) {
						if (currency.getLookupValue().equals(cur.getCurrency())) {
							ADDED = true;
							cur.setAmount(cur.getAmount()
									+ travelMiscExpense
											.getTravelMiscExpenseAmount());
							break;
						}
					}
					if (!ADDED) {
						Currency currencyObj = new Currency();
						currencyObj.setAmount(travelMiscExpense
								.getTravelMiscExpenseAmount());
						currencyObj.setCurrency(travelMiscExpense
								.getTravelMiscExpensecurrency());
						Currencies.add(currencyObj);
					}
				}
			}

		}
	}

	public void getBalancePay(AjaxBehaviorEvent e) {

		approvalTotal = travelExpense.getApprovalTotalValue();

		System.out.println("approvalTotal ::::::::" + approvalTotal);

		float balanceAmt = approvalTotal - travelExpense.getAdvanceTaken();

		System.out.println("balanceAmt ::::::::" + balanceAmt);

		travelExpense.setBalancePayOrReciveAmt(balanceAmt);

	}

	// Recommend Action
	public String recommendListener() {
		validateForm();
		if (FORM_VALID) {
			travelExpense.setRecommenderStatus("Recommended");
			if(travelReimbursementDAO.createTravelExpense(travelExpense) != null && travelRequestDAO.updateTravelRequest(travelRequest) != null){
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_INFO,
								" You have submitted successfully.", ""));
				System.out.println("AT CALLER METHOD: " + sendMessage()); // *******DONT	
			}else{
				System.out.println("FAILED");
			}
			
			
			

		}
		return null;
	}

	public String approveListener() {
		approverValidateForm();
		if (FORM_VALID) {
			travelExpense.setApproverStatus("Approved");
			travelReimbursementDAO.createTravelExpense(travelExpense);
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_INFO,
							" You have submitted successfully.", ""));

			// MAIL TRIGGERING CODE
			System.out.println("AT CALLER METHOD: " + approverMessage()); // *******DONT
																			// REMOVE*******
		}
		return null;
	}

	public void rejectListener(ActionEvent e) {
		validateForm();
		if (FORM_VALID) {
			travelExpense.setRecommenderStatus("Rejected");
			
			if(travelReimbursementDAO.createTravelExpense(travelExpense) != null && travelRequestDAO.updateTravelRequest(travelRequest) != null){

				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_INFO,
								" Claim rejected.", ""));
				System.out.println("AT CALLER METHOD: " + rejectMessage()); 
			}
		}
	}

	public void approverRejectListener(ActionEvent e) {
		approverValidateForm();
		if (FORM_VALID) {
			travelExpense.setApproverStatus("Rejected");
			if(travelReimbursementDAO.createTravelExpense(travelExpense) != null && travelRequestDAO.updateTravelRequest(travelRequest) != null){
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_INFO,
								" You are rejected travel expense form.", ""));

				// MAIL TRIGGERING CODE
				System.out.println("AT CALLER METHOD: " + approverRejectMessage()); // *******DONT
																					// REMOVE*******
			}

		}
	}

	// Mail COde

	public String sendMessage() {
		Map<String, String> hostsMap = WAMHostManager.getWAMHosts(context);
		String domainName = context.getInitParameter("domainName");
		String messageString = "";

		String fromPlace = ""; // DOMESTIC OVERSEAS
		String toPlace = "";
		if (travelRequest.getTravelType().equalsIgnoreCase("DOMESTIC")) {
			fromPlace = travelRequest.getTravelFrom_DO();
			toPlace = travelRequest.getTravelTo_DO();
		} else if (travelRequest.getTravelType().equalsIgnoreCase("OVERSEAS")) {
			fromPlace = travelRequest.getTravelFrom_OS();
			toPlace = travelRequest.getTravelTo_OS();
		} else {
			fromPlace = travelRequest.getTravelFrom_DO();
			toPlace = travelRequest.getTravelTo_OS();
		}
		SimpleDateFormat formate = new SimpleDateFormat("dd-MMM-yyyy");
		String fromDate = formate.format(travelRequest.getPeriodFrom());
		String toDate = formate.format(travelRequest.getPeriodTo());
		emailUtil = new EmailUtil();
		if (hostsMap.get(CommonLookup.DEV_EMAIL) == null) {
			String[] to = { travelExpense.getApprovedBy().getEmail() };
			emailUtil.setRecieverAddresses(to);			
		} else {
			String[] to = { hostsMap.get(CommonLookup.DEV_EMAIL) };
			emailUtil.setRecieverAddresses(to);			
		}

		String requestURL = "ac/reimbursement/approvetravelexpense.html?travelCode="
				+ travelCode
				+ "&expenseCode="
				+ travelExpenseCode
				+ "&employeeCode=" + employeeCode + "&activity=byApprover";
		String privateLink = "http://" + hostsMap.get(CommonLookup.PRIVATEHOST)
				+ "/" + domainName + "/" + requestURL;
		String publicLink = "http://" + hostsMap.get(CommonLookup.PUBLICHOST)
				+ "/" + domainName + "/" + requestURL;

		messageString = "Dear " + travelExpense.getApprovedBy().getFirstName()
				+ " " + travelExpense.getApprovedBy().getLastName() + ""
				+ ",<br /><br />" +

				"<table style='border: 1px solid #d9d9d9;'>"
				+ "<tr> <td>Employee Name</td><td> : </td><td>"
				+ travelRequest.getEmployee().getFirstName() + " "
				+ travelRequest.getEmployee().getLastName() + "</td></tr>"
				+ "<tr> <td>Employee Code</td><td> : </td><td>"
				+ travelRequest.getEmployee().getEmployeeCode() + " </td></tr>"
				+ "<tr> <td>Travel Request Code</td><td> : </td><td>"
				+ travelRequest.getTravelRequestCode() + " </td></tr>"
				+ "<tr> <td>Expense Request Code</td><td> : </td><td>"
				+ travelExpenseCode + " </td></tr>"
				+ "<tr> <td>Contact Number</td><td> : </td><td>"
				+ travelRequest.getEmployee().getTelephone() + " </td></tr>"
				+ "<tr> <td>Travel From</td><td> : </td><td>" + fromPlace
				+ " </td> <td>Travel To</td><td> : </td><td>" + toPlace
				+ " </td></tr>"
				+ "<tr> <td>Travel Start Date</td><td> : </td> <td>" + fromDate
				+ " </td><td>Return Date</td><td> : </td><td>" + toDate
				+ " </td></tr>" + "</table><br/>"
				+ "<a style='color:#FF9933;font-weight: bold;' href=\""
				+ privateLink + "\">"
				+ "Please click here to Approve/Reject travel expense request"
				+ "</a /><br />" + "(Employees who are in Hyderabad office)"
				+ "<br /><br />"
				+ "<a style='color:#FF9933;font-weight: bold;' href=\""
				+ publicLink + "\">"
				+ "Please click here to Approve/Reject travel expense request"
				+ "</a /><br />" + "(out side Hyderabad office)"
				+ "<br /><br />" +

				"Thanks & Regards, <br />" + CommonLookup.WAM_DEVTEAM_SIGNATURE;
		emailUtil.setMessage(messageString);
		emailUtil.setSenderEmail("podquick@erpanderp.com", "WAM - Dev Team");
		emailUtil.setSubject("WAM - Approve "
				+ travelRequest.getEmployee().getFirstName() + " "
				+ travelRequest.getEmployee().getLastName() + "( "
				+ travelExpenseCode + " ) - Travel Expense Request");

		SwingWorker worker = new SwingWorker<String, Object>() {
			@Override
			protected String doInBackground() throws Exception {
				EMAIL_MESSAGE = emailUtil.processAndSendEmail();
				return null;
			}

			@Override
			protected void done() {
				System.out.println("DONE " + EMAIL_MESSAGE);
			}
		};
		worker.execute();
		System.out.println("BEFORE RETURNING: " + EMAIL_MESSAGE);
		return EMAIL_MESSAGE;
	}

	// REJECT MAIL
	public String rejectMessage() {
		String messageString = "";

		String employeeMail = "sravani.m@erpanderp.com";
		// String approverMail = travelRequest.getApprover().getEmail();
		Map<String, String> hostsMap = WAMHostManager.getWAMHosts(context);
		emailUtil = new EmailUtil();
		if (hostsMap.get(CommonLookup.DEV_EMAIL) == null) {
			String[] to = { travelExpense.getApprovedBy().getEmail() };
			emailUtil.setRecieverAddresses(to);			
		} else {
			String[] to = { hostsMap.get(CommonLookup.DEV_EMAIL) };
			emailUtil.setRecieverAddresses(to);			
		}

		messageString = "Dear " + travelExpense.getEmployee().getFirstName()
				+ " " + travelExpense.getEmployee().getLastName() + ""
				+ ",<br /><br />" +

				"Your Travel Expense Claim " + "<b> ("
				+ travelExpenseCode + ") </b>"
				+ " needs some modifications. Please re-submit again.<br><br>"
				+ "<b>Approval Comments: </b> "
				+ travelExpense.getRecommenderComments() + "<br><br>" +

				"Thanks & Regards, <br />" + CommonLookup.WAM_DEVTEAM_SIGNATURE;
		
		emailUtil.setMessage(messageString);
		emailUtil.setSenderEmail("podquick@erpanderp.com", "WAM - Dev Team");
		emailUtil.setSubject("WAM - "
				+ travelRequest.getEmployee().getFirstName() + " "
				+ travelRequest.getEmployee().getLastName() + " ("
				+ travelExpenseCode
				+ ") - Re-Submit Again Travel Expense Request Form ");

		SwingWorker worker = new SwingWorker<String, Object>() {
			@Override
			protected String doInBackground() throws Exception {
				EMAIL_MESSAGE = emailUtil.processAndSendEmail();
				return null;
			}

			@Override
			protected void done() {
				System.out.println("DONE " + EMAIL_MESSAGE);
			}
		};
		worker.execute();
		System.out.println("BEFORE RETURNING: " + EMAIL_MESSAGE);
		return EMAIL_MESSAGE;
	}

	// APPROVER REJECT MAIL
	public String approverRejectMessage() {
		String messageString = "";

		String employeeMail = "sravani.m@erpanderp.com";
		// String approverMail = travelRequest.getApprover().getEmail();

		Map<String, String> hostsMap = WAMHostManager.getWAMHosts(context);
		emailUtil = new EmailUtil();
		if (hostsMap.get(CommonLookup.DEV_EMAIL) == null) {
			String[] to = { travelExpense.getEmployee().getEmail() };
			emailUtil.setRecieverAddresses(to);			
		} else {
			String[] to = { hostsMap.get(CommonLookup.DEV_EMAIL) };
			emailUtil.setRecieverAddresses(to);			
		}

		
		messageString = "Dear " + travelExpense.getEmployee().getFirstName()
				+ " " + travelExpense.getEmployee().getLastName() + ""
				+ ",<br /><br />" +

				"Your Travel Expense Request Form " + "<b> ("
				+ travelExpenseCode + ") </b>"
				+ " needs some modifications. Please re-submit again.<br><br>"
				+ "<b>Approval Comments: </b> "
				+ travelExpense.getApprovalComments() + "<br><br>" +

				"Thanks & Regards, <br />" + CommonLookup.WAM_DEVTEAM_SIGNATURE;
		
		emailUtil.setMessage(messageString);
		
		emailUtil.setSenderEmail("podquick@erpanderp.com", "WAM - Dev Team");

		emailUtil.setSubject("WAM - "
				+ travelRequest.getEmployee().getFirstName() + " "
				+ travelRequest.getEmployee().getLastName() + " ("
				+ travelExpenseCode
				+ ") - Re-Submit Again Travel Expense Request Form ");

		SwingWorker worker = new SwingWorker<String, Object>() {
			@Override
			protected String doInBackground() throws Exception {
				EMAIL_MESSAGE = emailUtil.processAndSendEmail();
				return null;
			}

			@Override
			protected void done() {
				System.out.println("DONE " + EMAIL_MESSAGE);
			}
		};
		worker.execute();
		System.out.println("BEFORE RETURNING: " + EMAIL_MESSAGE);
		return EMAIL_MESSAGE;
	}

	// REJECT MAIL
	public String approverMessage() {
		Map<String, String> hostsMap = WAMHostManager.getWAMHosts(context);
		String domainName = context.getInitParameter("domainName");
		String messageString = "";

		emailUtil = new EmailUtil();
		if (hostsMap.get(CommonLookup.DEV_EMAIL) == null) {
			String[] to = { travelExpense.getEmployee().getEmail() };
			emailUtil.setRecieverAddresses(to);			
		} else {
			String[] to = { hostsMap.get(CommonLookup.DEV_EMAIL) };
			emailUtil.setRecieverAddresses(to);
			//emailUtil.setCCAddresses(to);						
		}

		String requestURL = "ac/reimbursement/vieworprinttravelreimbursement.html?travelCode="
				+ travelCode
				+ "&expenseCode="
				+ travelExpenseCode
				+ "&employeeCode=" + employeeCode + "&activity=byApprover";
		String privateLink = "http://" + hostsMap.get(CommonLookup.PRIVATEHOST)
				+ "/" + domainName + "/" + requestURL;
		String publicLink = "http://" + hostsMap.get(CommonLookup.PUBLICHOST)
				+ "/" + domainName + "/" + requestURL;

		messageString = "Dear " + travelExpense.getEmployee().getFirstName()
				+ " " + travelExpense.getEmployee().getLastName() + ""
				+ ",<br /><br />" +

				"Your Travel Expense Request Form " + "<b> ("
				+ travelExpenseCode + ") </b>"
				+ " is approved successfully. <br><br>"
				+ "<b>Approval Comments: </b> "
				+ travelExpense.getApprovalComments() + "<br><br>" +

				"<a style='color:#FF9933;font-weight: bold;' href=\""
				+ privateLink + "\">"
				+ "Please click here to View/Print expense request form"
				+ "</a /><br />" + "(Employees who are in Hyderabad office)"
				+ "<br /><br />"
				+ "<a style='color:#FF9933;font-weight: bold;' href=\""
				+ publicLink + "\">"
				+ "Please click here to View/Print expense request form"
				+ "</a /><br />" + "(out side Hyderabad office)"
				+ "<br /><br />" +

				"Thanks & Regards, <br />" + CommonLookup.WAM_DEVTEAM_SIGNATURE;
		
		emailUtil.setMessage(messageString);
		emailUtil.setSenderEmail("podquick@erpanderp.com", "WAM - Dev Team");

		emailUtil.setSubject("WAM - "
						+ travelRequest.getEmployee().getFirstName() + " "
						+ travelRequest.getEmployee().getLastName() + " ("
						+ travelExpenseCode
						+ ") - Travel Expense request is approved");

		SwingWorker worker = new SwingWorker<String, Object>() {
			@Override
			protected String doInBackground() throws Exception {
				EMAIL_MESSAGE = emailUtil.processAndSendEmail();
				return null;
			}

			@Override
			protected void done() {
				System.out.println("DONE " + EMAIL_MESSAGE);
			}
		};
		worker.execute();
		System.out.println("BEFORE RETURNING: " + EMAIL_MESSAGE);
		return EMAIL_MESSAGE;
	}

	// Validations Test
	private void validateForm() {
		setFORM_VALID(true);
		if (ValidationUtil.isEmpty(travelExpense.getRecommenderComments(),
				"Your Comments", null, FacesContext.getCurrentInstance()) != null) {
			FORM_VALID = false;
		}
	}

	private void approverValidateForm() {
		setFORM_VALID(true);
		if (ValidationUtil.isEmpty(travelExpense.getApprovalComments(),
				"Your Comments", null, FacesContext.getCurrentInstance()) != null) {
			FORM_VALID = false;
		}

	}

	public void showNewPolicySection(ActionEvent e){
		SHOW_NEW_POLICY_SECTION = true;
		newPolicyAmount = new TravelExpenseAmount();
		
	}
	
	public void showNewApprovalAmountSection(ActionEvent e){
		SHOW_NEW_APPROVAL_AMOUNT_SECTION = true;
		newApprovalAmount = new TravelExpenseAmount();
		
	}
	
	public void addNewPolicyAmount(ActionEvent e) {
		boolean ADDED = false;
		for (TravelExpenseAmount expenseAmount : policyAmounts) {
			ADDED = false;
			if (expenseAmount.getCurrency().equals(newPolicyAmount.getCurrency())) {
				ADDED = true;
				travelRequest.getTravelExpenseAmounts().remove(expenseAmount);
				expenseAmount.setAmount(expenseAmount.getAmount() + newPolicyAmount.getAmount());
				travelRequest.getTravelExpenseAmounts().add(expenseAmount);			
				break;
			}
		}

		if (!ADDED) {
			newPolicyAmount.setAmountType(CommonLookup.TRAVEL_EXPENSE_POLICY_AMOUNT);
			newPolicyAmount.setCreateDate(new Date());
			newPolicyAmount.setCreatedBy(travelExpense.getRecommenderBy().getEmployeeCode());
			newPolicyAmount.setStatus(CommonLookup.STATUS_ACTIVE);
			newPolicyAmount.setTravelRequest(travelRequest);
			travelRequest.getTravelExpenseAmounts().add(newPolicyAmount);
			policyAmounts.add(newPolicyAmount);
		}
		
		Collections.sort(policyAmounts);
		
		SHOW_NEW_POLICY_SECTION = false;
	}
	
	public void addNewApprovalAmount(ActionEvent e) {
		boolean ADDED = false;
		for (TravelExpenseAmount expenseAmount : approvalAmounts) {
			ADDED = false;
			if (expenseAmount.getCurrency().equals(newApprovalAmount.getCurrency())) {
				ADDED = true;
				travelRequest.getTravelExpenseAmounts().remove(expenseAmount);
				expenseAmount.setAmount(expenseAmount.getAmount() + newApprovalAmount.getAmount());
				travelRequest.getTravelExpenseAmounts().add(expenseAmount);			
				break;
			}
		}

		if (!ADDED) {
			newApprovalAmount.setAmountType(CommonLookup.TRAVEL_EXPENSE_TYPE_APPROVAL_AMOUNT);
			newApprovalAmount.setCreateDate(new Date());
			newApprovalAmount.setCreatedBy(travelExpense.getRecommenderBy().getEmployeeCode());
			newApprovalAmount.setStatus(CommonLookup.STATUS_ACTIVE);
			newApprovalAmount.setTravelRequest(travelRequest);
			travelRequest.getTravelExpenseAmounts().add(newApprovalAmount);
			approvalAmounts.add(newApprovalAmount);
		}
		calculateBalance();
		SHOW_NEW_APPROVAL_AMOUNT_SECTION = false;
	}
	
	
	public void removePolicyAmount(ActionEvent e) {
		markedPolicyAmount = (TravelExpenseAmount) e.getComponent().getAttributes().get("policyAmount");
		travelRequest.getTravelExpenseAmounts().remove(markedPolicyAmount);
		policyAmounts.remove(markedPolicyAmount);
		Collections.sort(policyAmounts);
	}

	
	public void removeApprovelAmount(ActionEvent e) {
		markedApprovalAmount = (TravelExpenseAmount) e.getComponent().getAttributes().get("approvalAmount");
		travelRequest.getTravelExpenseAmounts().remove(markedApprovalAmount);
		approvalAmounts.remove(markedApprovalAmount);
		calculateBalance();
	}
	
	private void calculateBalance(){

		Map<String, Float> approvalAmountsMap = new HashMap<String, Float>();
		Map<String, Float> advanceAmountsMap = new HashMap<String, Float>();
		
		for(TravelExpenseAmount travelExpenseAmount : advanceTakenAmounts){
			advanceAmountsMap.put(travelExpenseAmount.getCurrency(), travelExpenseAmount.getAmount());
		}
		
		for(TravelExpenseAmount travelExpenseAmount : approvalAmounts){
			approvalAmountsMap.put(travelExpenseAmount.getCurrency(), travelExpenseAmount.getAmount());
		}
		
		balanceAmounts.clear();
		
		Set<String> currencies = new HashSet<String>();
		currencies.addAll(approvalAmountsMap.keySet());
		currencies.addAll(advanceAmountsMap.keySet());
		
		Date now = new Date();
		for(String currency : currencies){
			Float approvalAmount = approvalAmountsMap.get(currency) == null ? 0f : approvalAmountsMap.get(currency);
			Float advanceAmount = advanceAmountsMap.get(currency) == null ? 0f : advanceAmountsMap.get(currency);
			
			TravelExpenseAmount expenseAmount = new TravelExpenseAmount();
			expenseAmount.setAmount(approvalAmount - advanceAmount);
			expenseAmount.setAmountType(CommonLookup.TRAVEL_EXPENSE_TYPE_PAYABLE_RECIEVABLE);
			expenseAmount.setCreateDate(now);
			expenseAmount.setCreatedBy(travelExpense.getRecommenderBy().getEmployeeCode());
			expenseAmount.setCurrency(currency);
			expenseAmount.setStatus(CommonLookup.STATUS_ACTIVE);
			expenseAmount.setTravelRequest(travelRequest);
			balanceAmounts.add(expenseAmount);
		}
		
		List<TravelExpenseAmount> temp = new ArrayList<TravelExpenseAmount>();
		temp.addAll(travelRequest.getTravelExpenseAmounts());
		
		for(TravelExpenseAmount amount : temp){
			if(amount.getAmountType().equals(CommonLookup.TRAVEL_EXPENSE_TYPE_PAYABLE_RECIEVABLE)){
				travelRequest.getTravelExpenseAmounts().remove(amount);
			}
		}
		
		travelRequest.getTravelExpenseAmounts().addAll(balanceAmounts);
		Collections.sort(balanceAmounts);
		Collections.sort(approvalAmounts);				
	}
	
	// SETTERS AND GETTERS
	public String getEmployeeCode() {
		return employeeCode;
	}

	public void setEmployeeCode(String employeeCode) {
		this.employeeCode = employeeCode;
	}

	public String getTravelCode() {
		return travelCode;
	}

	public void setTravelCode(String travelCode) {
		this.travelCode = travelCode;
	}

	public EmployeeDAO getEmployeeDAO() {
		return employeeDAO;
	}

	public void setEmployeeDAO(EmployeeDAO employeeDAO) {
		this.employeeDAO = employeeDAO;
	}

	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	public TravelReimbursementDAO getTravelReimbursementDAO() {
		return travelReimbursementDAO;
	}

	public void setTravelReimbursementDAO(
			TravelReimbursementDAO travelReimbursementDAO) {
		this.travelReimbursementDAO = travelReimbursementDAO;
	}

	public TravelExpense getTravelExpense() {
		return travelExpense;
	}

	public void setTravelExpense(TravelExpense travelExpense) {
		this.travelExpense = travelExpense;
	}

	public String getTravelExpenseCode() {
		return travelExpenseCode;
	}

	public void setTravelExpenseCode(String travelExpenseCode) {
		this.travelExpenseCode = travelExpenseCode;
	}

	public TravelRequest getTravelRequest() {
		return travelRequest;
	}

	public void setTravelRequest(TravelRequest travelRequest) {
		this.travelRequest = travelRequest;
	}

	public TravelRequestDAO getTravelRequestDAO() {
		return travelRequestDAO;
	}

	public void setTravelRequestDAO(TravelRequestDAO travelRequestDAO) {
		this.travelRequestDAO = travelRequestDAO;
	}

	public List<TransportExpense> getTransportExpensesDetailsList() {
		return transportExpensesDetailsList;
	}

	public void setTransportExpensesDetailsList(
			List<TransportExpense> transportExpensesDetailsList) {
		this.transportExpensesDetailsList = transportExpensesDetailsList;
	}

	public List<LodgingExpense> getLodgingExpenseDetailsList() {
		return lodgingExpenseDetailsList;
	}

	public void setLodgingExpenseDetailsList(
			List<LodgingExpense> lodgingExpenseDetailsList) {
		this.lodgingExpenseDetailsList = lodgingExpenseDetailsList;
	}

	public List<BoardingExpense> getBoardingExpenseDetailsList() {
		return boardingExpenseDetailsList;
	}

	public void setBoardingExpenseDetailsList(
			List<BoardingExpense> boardingExpenseDetailsList) {
		this.boardingExpenseDetailsList = boardingExpenseDetailsList;
	}

	public List<TravelMiscExpense> getTravelMiscExpenseDetailsList() {
		return travelMiscExpenseDetailsList;
	}

	public void setTravelMiscExpenseDetailsList(
			List<TravelMiscExpense> travelMiscExpenseDetailsList) {
		this.travelMiscExpenseDetailsList = travelMiscExpenseDetailsList;
	}

	public List<Currency> getCurrencies() {
		return Currencies;
	}

	public void setCurrencies(List<Currency> currencies) {
		Currencies = currencies;
	}

	public String getActivity() {
		return activity;
	}

	public void setActivity(String activity) {
		this.activity = activity;
	}

	public CustomLookupDAO getCustomLookupDAO() {
		return customLookupDAO;
	}

	public void setCustomLookupDAO(CustomLookupDAO customLookupDAO) {
		this.customLookupDAO = customLookupDAO;
	}

	public List<LookupValue> getLookUpValuesList() {
		return lookUpValuesList;
	}

	public void setLookUpValuesList(List<LookupValue> lookUpValuesList) {
		this.lookUpValuesList = lookUpValuesList;
	}

	public float getApprovalTotal() {
		return approvalTotal;
	}

	public void setApprovalTotal(float approvalTotal) {
		this.approvalTotal = approvalTotal;
	}

	public boolean isFORM_VALID() {
		return FORM_VALID;
	}

	public void setFORM_VALID(boolean fORM_VALID) {
		FORM_VALID = fORM_VALID;
	}

	public Employee getEmployeeVP() {
		return employeeVP;
	}

	public void setEmployeeVP(Employee employeeVP) {
		this.employeeVP = employeeVP;
	}

	public TimeZone getTimeZone() {
		return timeZone;
	}

	public void setTimeZone(TimeZone timeZone) {
		this.timeZone = timeZone;
	}

	public Map<String,String> getCurrencyMap() {
		return currencyMap;
	}

	public void setCurrencyMap(Map<String,String> currencyMap) {
		this.currencyMap = currencyMap;
	}

	public List<TravelExpenseAmount> getPolicyAmounts() {
		return policyAmounts;
	}

	public void setPolicyAmounts(List<TravelExpenseAmount> policyAmounts) {
		this.policyAmounts = policyAmounts;
	}

	public List<TravelExpenseAmount> getAdvanceTakenAmounts() {
		return advanceTakenAmounts;
	}

	public void setAdvanceTakenAmounts(List<TravelExpenseAmount> advanceTakenAmounts) {
		this.advanceTakenAmounts = advanceTakenAmounts;
	}

	public List<TravelExpenseAmount> getApprovalAmounts() {
		return approvalAmounts;
	}

	public void setApprovalAmounts(List<TravelExpenseAmount> approvalAmounts) {
		this.approvalAmounts = approvalAmounts;
	}

	public List<TravelExpenseAmount> getBalanceAmounts() {
		return balanceAmounts;
	}

	public void setBalanceAmounts(List<TravelExpenseAmount> balanceAmounts) {
		this.balanceAmounts = balanceAmounts;
	}

	public boolean isSHOW_NEW_POLICY_SECTION() {
		return SHOW_NEW_POLICY_SECTION;
	}

	public void setSHOW_NEW_POLICY_SECTION(boolean sHOW_NEW_POLICY_SECTION) {
		SHOW_NEW_POLICY_SECTION = sHOW_NEW_POLICY_SECTION;
	}

	public boolean isSHOW_NEW_APPROVAL_AMOUNT_SECTION() {
		return SHOW_NEW_APPROVAL_AMOUNT_SECTION;
	}

	public void setSHOW_NEW_APPROVAL_AMOUNT_SECTION(
			boolean sHOW_NEW_APPROVAL_AMOUNT_SECTION) {
		SHOW_NEW_APPROVAL_AMOUNT_SECTION = sHOW_NEW_APPROVAL_AMOUNT_SECTION;
	}

	public TravelExpenseAmount getNewApprovalAmount() {
		return newApprovalAmount;
	}

	public void setNewApprovalAmount(TravelExpenseAmount newApprovalAmount) {
		this.newApprovalAmount = newApprovalAmount;
	}

	public TravelExpenseAmount getNewPolicyAmount() {
		return newPolicyAmount;
	}

	public void setNewPolicyAmount(TravelExpenseAmount newPolicyAmount) {
		this.newPolicyAmount = newPolicyAmount;
	}

	public TravelExpenseAmount getMarkedPolicyAmount() {
		return markedPolicyAmount;
	}

	public void setMarkedPolicyAmount(TravelExpenseAmount markedPolicyAmount) {
		this.markedPolicyAmount = markedPolicyAmount;
	}

	public TravelExpenseAmount getMarkedApprovalAmount() {
		return markedApprovalAmount;
	}

	public void setMarkedApprovalAmount(TravelExpenseAmount markedApprovalAmount) {
		this.markedApprovalAmount = markedApprovalAmount;
	}

}
